package com.xlh.service.problem.impl;

import com.github.pagehelper.PageHelper;
import com.github.pagehelper.PageInfo;
import com.xlh.dao.problem.PcConfigMapper;
import com.xlh.dao.problem.PcConfigMapperExt;
import com.xlh.dto.PageDTO;
import com.xlh.dto.problem.ForbiddenDTO;
import com.xlh.dto.problem.ProblemDTO;
import com.xlh.dto.problem.ProblemExtDTO;
import com.xlh.dto.problem.ReplyDTO;
import com.xlh.dto.user.ClassDTO;
import com.xlh.dto.user.UserInfoDTO;
import com.xlh.enums.LocalResourcesEnum;
import com.xlh.enums.PcConfigEnum;
import com.xlh.enums.WebsocketMessageEnum;
import com.xlh.enums.user.RoleEnum;
import com.xlh.enums.user.SexEnum;
import com.xlh.exception.common.GlobalException;
import com.xlh.param.problem.ForbiddenParam;
import com.xlh.param.problem.ProblemParam;
import com.xlh.param.problem.ProblemPostParam;
import com.xlh.param.problem.ReplyPostParam;
import com.xlh.pojo.problem.Forbidden;
import com.xlh.pojo.problem.PcConfig;
import com.xlh.pojo.problem.PcConfigExample;
import com.xlh.pojo.user.User;
import com.xlh.security.UserInfoHolder;
import com.xlh.service.problem.ForbiddenService;
import com.xlh.service.problem.ProblemCommunicationService;
import com.xlh.service.problem.ProblemService;
import com.xlh.service.problem.ReplyService;
import com.xlh.service.user.ClassService;
import com.xlh.service.user.UserService;
import com.xlh.websocket.GlobalWebsocket;
import org.apache.commons.collections.CollectionUtils;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Service;

import java.util.List;
import java.util.stream.Collectors;

/**
 * @author sy
 */
@Service
public class ProblemCommunicationServiceImpl implements ProblemCommunicationService {
    @Autowired
    private ForbiddenService forbiddenService;
    @Autowired
    private ProblemService problemService;
    @Autowired
    private ReplyService replyService;
    @Autowired
    private ClassService classService;
    @Autowired
    private UserService userService;

    @Autowired
    private PcConfigMapper pcConfigMapper;
    @Autowired
    private PcConfigMapperExt pcConfigMapperExt;

    @Autowired
    private UserInfoHolder userInfoHolder;

    public ProblemExtDTO listProblemPages(Integer pageNum, Integer pageSize, ProblemParam problemParam) {
        ProblemExtDTO problemExtDTO = new ProblemExtDTO();

        PageHelper.startPage(pageNum, pageSize);
        List<ProblemDTO> problemDTOList = problemService.listProblemPages(problemParam);
        problemDTOList.forEach(dto -> {
            dto.setIcon(LocalResourcesEnum.SYSTEM_FILE.getMappingUrl(dto.getIcon()));
            RoleEnum roleEnum = RoleEnum.getByCode(dto.getRole());
            if (roleEnum != null) dto.setRoleName(roleEnum.getRoleName());
        });

        PageInfo<ProblemDTO> pageInfo = new PageInfo<>(problemDTOList);
        PageDTO pageDTO = new PageDTO(pageInfo);

        //获取当前登录人id
        User user = userInfoHolder.getUser();
        problemParam.setUserId(user.getId());

        Forbidden forbidden = forbiddenService.selectByUserIdCourseId(problemParam.getUserId(), problemParam.getCourseId());
        if (forbidden.getId() != null) {
            problemExtDTO.setForbidden(forbidden.getIsForbidden());
        } else {
            problemExtDTO.setForbidden(false);
        }
        problemExtDTO.setPageDTO(pageDTO);

        return problemExtDTO;
    }

    public PageDTO<ProblemDTO> listMyProblemPages(Integer pageNum, Integer pageSize, ProblemParam problemParam) {
        //从session获取当前登录人id
        User user = userInfoHolder.getUser();
        problemParam.setUserId(user.getId());

        PageHelper.startPage(pageNum, pageSize);
        List<ProblemDTO> problemDTOList = problemService.listProblemPages(problemParam);
        problemDTOList.forEach(dto -> {
            dto.setIcon(LocalResourcesEnum.SYSTEM_FILE.getMappingUrl(dto.getIcon()));
            RoleEnum roleEnum = RoleEnum.getByCode(dto.getRole());
            if (roleEnum != null) dto.setRoleName(roleEnum.getRoleName());
        });

        PageInfo<ProblemDTO> pageInfo = new PageInfo<>(problemDTOList);
        return new PageDTO<>(pageInfo);
    }

    public ProblemDTO problemDetail(Long id) {
        ProblemDTO problemDTO = problemService.problemDetailById(id);
        problemDTO.setIcon(LocalResourcesEnum.SYSTEM_FILE.getMappingUrl(problemDTO.getIcon()));
        RoleEnum roleEnum = RoleEnum.getByCode(problemDTO.getRole());
        if (roleEnum != null) problemDTO.setRoleName(roleEnum.getRoleName());

        List<ReplyDTO> replyDTOList = replyService.replyList(id);
        replyDTOList.forEach(dto -> {
            dto.setIcon(LocalResourcesEnum.SYSTEM_FILE.getMappingUrl(dto.getIcon()));
            RoleEnum roleEnum1 = RoleEnum.getByCode(dto.getRole());
            if (roleEnum1 != null) dto.setRoleName(roleEnum1.getRoleName());
        });

        problemDTO.setProblemCount(replyDTOList.size());
        problemDTO.setListReply(replyDTOList);

        //获取当前登录人id
        ProblemParam problemParam = new ProblemParam();
        User user = userInfoHolder.getUser();
        problemParam.setUserId(user.getId());

        problemParam.setCourseId(problemDTO.getCourseId());
        Forbidden forbidden = forbiddenService.selectByUserIdCourseId(problemParam.getUserId(), problemParam.getCourseId());
        if (forbidden.getId() != null) {
            problemDTO.setForbidden(forbidden.getIsForbidden());
        } else {
            problemDTO.setForbidden(false);
        }

        return problemDTO;
    }

    public ProblemDTO myAnswerProblemDetail(Long id) {

        //获取当前登录人id
        ProblemParam problemParam = new ProblemParam();
        User user = userInfoHolder.getUser();

        ProblemDTO problemDTO = problemService.problemDetailById(id);
        problemDTO.setIcon(LocalResourcesEnum.SYSTEM_FILE.getMappingUrl(problemDTO.getIcon()));
        RoleEnum roleEnum = RoleEnum.getByCode(problemDTO.getRole());
        if (roleEnum != null) problemDTO.setRoleName(roleEnum.getRoleName());

        ReplyPostParam replyPostParam = new ReplyPostParam();
        replyPostParam.setProblemId(id);
        replyPostParam.setUserId(user.getId());
        List<ReplyDTO> replyDTOList = replyService.myReplyList(replyPostParam);
        replyDTOList.forEach(dto -> {
            dto.setIcon(LocalResourcesEnum.SYSTEM_FILE.getMappingUrl(dto.getIcon()));
            RoleEnum roleEnum1 = RoleEnum.getByCode(dto.getRole());
            if (roleEnum1 != null) dto.setRoleName(roleEnum1.getRoleName());
        });

        problemDTO.setProblemCount(replyDTOList.size());
        problemDTO.setListReply(replyDTOList);

        problemParam.setUserId(user.getId());
        problemParam.setCourseId(problemDTO.getCourseId());
        Forbidden forbidden = forbiddenService.selectByUserIdCourseId(problemParam.getUserId(), problemParam.getCourseId());
        if (forbidden.getId() != null) {
            problemDTO.setForbidden(forbidden.getIsForbidden());
        } else {
            problemDTO.setForbidden(false);
        }

        return problemDTO;
    }

    public PageDTO<ProblemDTO> listMyProblemReplyPages(Integer pageNum, Integer pageSize, ProblemParam problemParam) {
        //从session里获取当前用户id
        User user = userInfoHolder.getUser();
        problemParam.setUserId(user.getId());

        PageHelper.startPage(pageNum, pageSize);
        List<ProblemDTO> problemDTOList = problemService.listMyProblemReplyPages(problemParam);
        problemDTOList.forEach(dto -> {
            dto.setIcon(LocalResourcesEnum.SYSTEM_FILE.getMappingUrl(dto.getIcon()));
            RoleEnum roleEnum = RoleEnum.getByCode(dto.getRole());
            if (roleEnum != null) dto.setRoleName(roleEnum.getRoleName());
        });

        PageInfo<ProblemDTO> pageInfo = new PageInfo<>(problemDTOList);

        return new PageDTO<>(pageInfo);
    }

    public PageDTO<ForbiddenDTO> forbiddenWordsListPage(Integer pageNum, Integer pageSize, ProblemParam problemParam) {
        PageHelper.startPage(pageNum, pageSize);
        List<ForbiddenDTO> forbiddenDTOList = forbiddenService.forbiddenWordsListPage(problemParam);
        forbiddenDTOList.forEach(dto -> {
            SexEnum sexEnum = SexEnum.getByCode(dto.getSex());
            if (sexEnum != null) dto.setSexName(sexEnum.getMessage());
        });

        PageInfo<ForbiddenDTO> pageInfo = new PageInfo<>(forbiddenDTOList);

        return new PageDTO<>(pageInfo);
    }

    public void forbiddenWords(ForbiddenParam param) {
        List<Long> userIds = param.getUserIds();
        if (CollectionUtils.isNotEmpty(userIds)) {
            for (Long userId : userIds) {
                Forbidden forbidden = forbiddenService.selectByUserIdCourseId(userId, param.getCourseId());
                forbidden.setIsForbidden(param.getIsForbidden());
                if (forbidden.getId() == null) {
                    forbidden.setCourseId(param.getCourseId());
                    forbidden.setUserId(userId);
                    forbiddenService.insertSelective(forbidden);
                } else {
                    forbiddenService.updateByPrimaryKeySelective(forbidden);
                }
            }
        }
    }

    public void askQuestions(ProblemPostParam problemPostParam) {
        //从session里获取当前用户id
        User user = userInfoHolder.getUser();
        problemPostParam.setUserId(user.getId());

        problemService.askQuestions(problemPostParam);

    }

    public void toAnswer(ReplyPostParam replyPostParam) {
        //从session里获取当前用户id
        User user = userInfoHolder.getUser();
        replyPostParam.setUserId(user.getId());

        replyService.toAnswer(replyPostParam);

        problemService.changeNumberAnswers(replyPostParam);
    }

    public void batchDeletionAnswer(List<Integer> ids) {

        if (CollectionUtils.isEmpty(ids)) {
            throw new GlobalException("参数不正确");
        }
        replyService.batchDeletionAnswer(ids);

    }

    public void batchDeletionQuestion(List<Integer> ids) {

        if (CollectionUtils.isEmpty(ids)) {
            throw new GlobalException("参数不正确");
        }
        problemService.batchDeletionQuestion(ids);

        replyService.batchDeletionAnswerByProblemId(ids);


    }

    public PcConfig getProblemSwitch(Long courseId) {
        PcConfigExample pcConfigExample = new PcConfigExample();
        pcConfigExample.or().andCourseIdEqualTo(courseId);
        List<PcConfig> pcConfigList = pcConfigMapper.selectByExample(pcConfigExample);

        if (CollectionUtils.isEmpty(pcConfigList)) {
            PcConfig pcConfig = new PcConfig();
            pcConfig.setCourseId(courseId);
            pcConfig.setPcSwitch(PcConfigEnum.PC_CONFIG_OPEN.getCode());
            pcConfigMapperExt.controlSwitch(pcConfig);
            return pcConfig;
        }

        return pcConfigList.get(0);

    }

    public void controlSwitch(PcConfig pcConfig) {
        User user = userInfoHolder.getUser();

        pcConfigMapperExt.controlSwitch(pcConfig);

        WebsocketMessageEnum en = pcConfig.getPcSwitch() ?
                WebsocketMessageEnum.PROBLEM_COMMUNICATION_CLOSE :
                WebsocketMessageEnum.PROBLEM_COMMUNICATION_OPEN;

        // todo 需要张锐进行检查。 原先没有userId，查询课程下的所有班级。现在增加助教功能，应该变成 当前教师，这门课程下的所有未结课的班级
        List<ClassDTO> classList = classService.listClassCourse(
                pcConfig.getCourseId(), userInfoHolder.getUserId(), null, false, null);
        if (CollectionUtils.isEmpty(classList)) {
            return;
        }

        List<Long> classIds = classList.stream().map(ClassDTO::getId).collect(Collectors.toList());
        List<UserInfoDTO> studentList = userService.queryClassUser(classIds, null);
        if (CollectionUtils.isEmpty(studentList)) {
            return;
        }

        List<Long> studentIds = studentList.stream().map(UserInfoDTO::getId).collect(Collectors.toList());

        GlobalWebsocket.problemCommunicationMessage(user.getId(), user.getName(), en, studentIds);
    }
}
